package cn.tedu.submarine;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 整个游戏窗口
 */
public class World extends JPanel {
    /**
     * 窗口的宽
     */
    public static final int WIDTH = 641;
    /**
     * 窗口的高
     */
    public static final int HEIGHT = 479;
    /**
     * 运行状态
     */
    public static final int RUNNING = 0;
    /**
     * 暂停状态
     */
    public static final int PAUSE = 1;
    /**
     * 游戏结束状态
     */
    public static final int GAME_OVER = 2;
    /**
     * 当前状态
     */
    private int state = RUNNING;

    /**
     * 创建战舰对象、战舰对象、水雷数组、炸弹数组
     */
    private Battleship ship = new Battleship();
    private SeaObject[] submarines = {};
    private Mine[] mines = {};
    private Bomb[] bombs = {};

    /**
     * 生成潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇)对象
     * @return 返回潜艇
     */
    private SeaObject nextSubmarine(){
        Random rand = new Random();
        int type = rand.nextInt(20);
        if(type<10){
            //0到9时，返回侦察潜艇对象
            return new ObserveSubmarine();
        }else if(type<16){
            //10到15时，返回鱼雷潜艇对象
            return new TorpedoSubmarine();
        }else{
            //16到19时，返回水雷潜艇对象
            return new MineSubmarine();
        }
    }

    /**
     * 潜艇入场计数
     */
    private int subEnterIndex = 0;

    private void submarineEnterAction(){
        subEnterIndex++;
        if(subEnterIndex%40==0){
            //获取潜艇对象
            SeaObject obj = nextSubmarine();
            submarines = Arrays.copyOf(submarines,submarines.length+1);
            submarines[submarines.length-1] = obj;
        }
    }

    /**
     * 水雷入场计数
     */
    private int mineEnterIndex = 0;

    private void mineEnterAction(){
        mineEnterIndex++;
        if(mineEnterIndex%100==0){
            for(int i=0;i<submarines.length;i++){
                if(submarines[i] instanceof MineSubmarine){
                    MineSubmarine ms = (MineSubmarine)submarines[i];
                    //获取水雷对象
                    Mine obj = ms.shootMine();
                    mines = Arrays.copyOf(mines,mines.length+1);
                    mines[mines.length-1] = obj;
                }
            }
        }
    }

    /**
     * 海洋对象移动
     */
    private void moveAction(){
        for(int i=0;i<submarines.length;i++){
            submarines[i].move();
        }
        for(int i=0;i<mines.length;i++){
            mines[i].move();
        }
        for(int i=0;i<bombs.length;i++){
            bombs[i].move();
        }
    }


    /**
     * 删除越界的海洋对象
     */
    public void outOfBoundsAction(){
        //遍历所有潜艇
        for(int i=0;i<submarines.length;i++){
            if(submarines[i].isOutOfBounds() || submarines[i].isDead()){
                submarines[i] = submarines[submarines.length-1];
                submarines = Arrays.copyOf(submarines,submarines.length-1);
            }
        }
        //遍历所有水雷
        for(int i=0;i<mines.length;i++){
            if(mines[i].isOutOfBounds() || mines[i].isDead()){
                mines[i] = mines[mines.length-1];
                mines = Arrays.copyOf(mines,mines.length-1);
            }
        }
        //遍历所有炸弹
        for(int i=0;i<bombs.length;i++){
            if(bombs[i].isOutOfBounds() || bombs[i].isDead()){
                bombs[i] = bombs[bombs.length-1];
                bombs = Arrays.copyOf(bombs,bombs.length-1);
            }
        }
    }

    /**
     * 定义玩家的分数
     */
    private int score = 0; //玩家得分

    public void bombBangAction(){
        for(int i=0;i<bombs.length;i++){
            Bomb bom = bombs[i];
            for(int j=0;j<submarines.length;j++){
                SeaObject sco = submarines[j];
                if(bom.isLive() && sco.isLive() && sco.isHit(bom)){
                    sco.goDead();
                    bom.goDead();
                    if(sco instanceof EnemyScore){
                        EnemyScore es = (EnemyScore)sco;
                        score += es.getScore();
                    }
                    if(sco instanceof EnemyLife){
                        EnemyLife el = (EnemyLife)sco;
                        int num = el.getLife();
                        ship.addLife(num);
                    }
                }
            }
        }
    }


    /**
     * 水雷撞上战舰，战舰减命
     */
    public void mineBangAction(){
        for(int i=0;i<mines.length;i++){
            Mine m = mines[i];
            if(m.isLive() && ship.isLive() && m.isHit(ship)){
                m.goDead();
                ship.subtractLife();
            }
        }
    }

    /**
     * 战舰的命数小于0，表示游戏结束
     */
    public void checkGameOverAction(){
        if(ship.getLife()<=0){
            state = GAME_OVER;
        }
    }

    /**
     * 启动程序的执行
     */
    private void action(){
        //键盘侦听器---不要求掌握
        KeyAdapter k = new KeyAdapter() {
            /** 重写keyReleased()按键抬起事件 keyPressed()按键按下事件 */
            public void keyReleased(KeyEvent e) { //按键抬起时会自动触发---不要求掌握
                if(e.getKeyCode()==KeyEvent.VK_P){ //抬起P键---不要求掌握
                    if(state==RUNNING){ //运行状态时修改为暂停状态
                        state = PAUSE;
                    }else if(state==PAUSE){ //暂停状态时修改为运行状态
                        state = RUNNING;
                    }
                }

                if(state==RUNNING){  //仅在运行状态时执行
                    //如下代码仅在运行状态时，才能执行到
                    if(e.getKeyCode()==KeyEvent.VK_SPACE){ //抬起空格键---不要求掌握
                        Bomb obj = ship.shootBomb(); //获取炸弹对象
                        bombs = Arrays.copyOf(bombs,bombs.length+1); //扩容
                        bombs[bombs.length-1] = obj; //将obj添加到bombs最后一个元素上
                    }
                    if(e.getKeyCode()==KeyEvent.VK_LEFT){ //抬起左键头---不要求掌握
                        ship.moveLeft(); //战舰左移
                    }
                    if(e.getKeyCode()==KeyEvent.VK_RIGHT){ //抬起右键头---不要求掌握
                        ship.moveRight(); //战舰右移
                    }
                }
            }
        };
        this.addKeyListener(k);

        //定时器对象
        Timer timer = new Timer();
        int interval = 10;
        timer.schedule(new TimerTask() {
            public void run() {
                if(state==RUNNING){
                    submarineEnterAction();
                    mineEnterAction();
                    moveAction();
                    outOfBoundsAction();
                    bombBangAction();
                    mineBangAction();
                    checkGameOverAction();
                    repaint();
                }
            }
        }, interval, interval);
    }

    /**
     * 重写paint()画
     * @param g 系统自带的画笔
     */
    public void paint(Graphics g){
        //画海洋图
        Images.sea.paintIcon(null,g,0,0);
        //画战舰
        ship.paintImage(g);
        for(int i=0;i<submarines.length;i++){
            //画潜艇
            submarines[i].paintImage(g);
        }
        for(int i=0;i<mines.length;i++){
            //画水雷
            mines[i].paintImage(g);
        }
        for(int i=0;i<bombs.length;i++){
            //画炸弹
            bombs[i].paintImage(g);
        }
        g.drawString("SCORE: "+score,200,50);
        g.drawString("LIFE: "+ship.getLife(),400,50);
        //若当前状态为游戏结束状态
        if(state==GAME_OVER){
            Images.gameover.paintIcon(null,g,0,0);
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        World world = new World();
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH+16, HEIGHT+40);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true);

        //启动程序的执行
        world.action();
    }


}
